package com.zlt.appparking.controller;

import com.alibaba.fastjson.JSONObject;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.zlt.appparking.dto.AppUserDTO;

import com.zlt.appparking.service.AppUserService;
import com.zlt.appparking.utils.CodeUtil.CodeUtil;
import com.zlt.appparking.utils.QnyUtil;
import com.zlt.appparking.utils.RegularUtil;
import com.zlt.appparking.utils.StringUtil;
import com.zlt.appparking.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.TimeUnit;


@Slf4j
@RestController
@RequestMapping("app_user")
public class AppUserController {

    @Autowired
    private DefaultKaptcha defaultKaptcha;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private AppUserService appUserService;


    /**
     * 修改个人信息
     *
     * @param appUserDTO
     * @return
     */
    @PutMapping("updateAppUser")
    public Result updateAppUser(@RequestBody AppUserDTO appUserDTO, @RequestParam("file") MultipartFile file) {

        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("修改失败，手机号已存在");
        }

        try {
            InputStream inputStream = file.getInputStream();
            //文件名+文件后缀
            String originalFilename = file.getOriginalFilename();
            if (originalFilename != null) {
                String fileName = StringUtil.uuid() + originalFilename.substring(originalFilename.lastIndexOf(".")); //文件名（uuid）+ 文件后缀
                String url = QnyUtil.upload(inputStream, fileName);
                appUserDTO.setAuPhoto(url);

                boolean success = appUserService.updateAppUser(appUserDTO);
                return success ? Result.ok("修改成功") : Result.error("修改失败");
            } else {
                return Result.error("上传图片失败");
            }
        } catch (IOException e) {
            return Result.error(e.getMessage());
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }


    /**
     * 使用手机号验证码登录  获取手机验证码
     *
     * @param appUserDTO
     * @param response
     * @return
     */
    @PostMapping("loginPhoneCode")
    public Result loginPhoneCode(@RequestBody AppUserDTO appUserDTO, HttpServletResponse response) {
        log.debug("在获取手机验证码的人为{}", appUserDTO);

        //手机号码验证
        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("手机号不正确");
        }

        //对phoneCode进行处理 拿到code
        String phoneCode = CodeUtil.logPhoneCode(appUserDTO.getAuPhone());
        JSONObject object = JSONObject.parseObject(phoneCode);
        JSONObject params = object.getJSONObject("params");
        String code = (String) params.get("code");


        String uuid = StringUtil.uuid();
        response.setHeader("loginPhoneCode", uuid);
        redisTemplate.opsForValue().set(uuid, code, 5, TimeUnit.MINUTES);


        return Result.ok("发送成功", code);
    }


    /**
     * 获取修改密码 手机验证码
     *
     * @param appUserDTO
     * @param response
     * @return
     */
    @PostMapping("forgetPhoneCode")
    public Result forgetPhoneCode(@RequestBody AppUserDTO appUserDTO, HttpServletResponse response) {
        log.debug("在获取手机验证码的人为{}", appUserDTO);

        //手机号码验证
        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("手机号不正确");
        }

        //对phoneCode进行处理 拿到code
        String phoneCode = CodeUtil.modifyPhoneCode(appUserDTO.getAuPhone());
        JSONObject object = JSONObject.parseObject(phoneCode);
        JSONObject params = object.getJSONObject("params");
        String code = (String) params.get("code");


        String uuid = StringUtil.uuid();
        response.setHeader("forgetPhoneCode", uuid);
        redisTemplate.opsForValue().set(uuid, code, 5, TimeUnit.MINUTES);


        return Result.ok("发送成功", code);
    }

    /**
     * 获取注册 手机验证码
     *
     * @param appUserDTO
     * @param response
     * @return
     * @throws ServletException
     * @throws IOException
     */
    @PostMapping("regPhoneCode")
    public Result regPhoneCode(@RequestBody AppUserDTO appUserDTO, HttpServletResponse response) throws ServletException, IOException {

        log.debug("在获取手机验证码的人为{}", appUserDTO);

        //手机号码验证
        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("手机号不正确");
        }

        //对phoneCode进行处理 拿到code
        String phoneCode = CodeUtil.regPhoneCode(appUserDTO.getAuPhone());
        JSONObject object = JSONObject.parseObject(phoneCode);
        JSONObject params = object.getJSONObject("params");
        String code = (String) params.get("code");


        String uuid = StringUtil.uuid();
        response.setHeader("regPhoneCode", uuid);
        redisTemplate.opsForValue().set(uuid, code, 10, TimeUnit.MINUTES);


        return Result.ok("发送成功", code);
    }

    /**
     * 获取登录验证码
     *
     * @param response
     * @return
     */
    @GetMapping("kaptcha")
    public Result kaptcha(HttpServletResponse response) {
        String text = defaultKaptcha.createText();
        log.debug("验证码为{}", text);
        String uuid = StringUtil.uuid();
        response.setHeader("token", uuid);
        //将生成的文字放入redis
        redisTemplate.opsForValue().set(uuid, text, 5, TimeUnit.MINUTES);
        //创建图片
        BufferedImage image = defaultKaptcha.createImage(text);
        //将图片转换成字符串
        String s = StringUtil.changeImageToString(image);
        return Result.ok("获取成功", s);
    }


    /**
     * 用户注册
     *
     * @param appUserDTO
     * @param response
     * @return
     */
    @PostMapping("reg")
    public Result reg(@RequestHeader(name = "regPhoneCode") String token, @RequestBody AppUserDTO appUserDTO, HttpServletResponse response) {
        /*
                登录可以使用username (用户id 系统给的身份id)，密码登录，或者手机号，密码登录，或者手机号和手机验证码登录
                注册 username(用户id 系统给的身份id) 10位 随机数 还要判断10位随机数 是否重复
                     password密码 必填  可以正则 设置密码格式
                    salt密码盐   4位还是6位  随机数
                    nickname  昵称  非必填 (用户昵称)  可以不用在注册时设置  给一个随机或者默认的值(字符串之类的)
                    phone 手机号  必填  进行手机号的正则验证
                    phono  用户头像  可以不用在注册时设置  给一个默认的头像
         */

        //数据校验
        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("手机号不正确");
        }

        //校验验证码
        String PhoneCode = appUserDTO.getPhoneCode();
        String s = (String) redisTemplate.opsForValue().get(token);

        if (!StringUtil.isNotNull(s)) {
            return Result.error("验证码过期");
        }
        if (!s.equalsIgnoreCase(PhoneCode)) {
            return Result.error("验证码错误");
        }

        try {
            boolean success = appUserService.reg(appUserDTO);
            return success ? Result.ok("注册成功") : Result.error("注册失败");
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }


    }

    /**
     * 用户登录
     *
     * @param token
     * @param appUserDTO
     * @param response
     * @return
     */

    @PostMapping("login")
    public Result login(@RequestHeader(name = "token") String token, @RequestBody AppUserDTO appUserDTO, HttpServletResponse response) {
        // 数据校验

        // 首先校验验证码
        String o = (String) redisTemplate.opsForValue().get(token);
        if (o == null) {
            return Result.error("验证码过期");
        }
        if (!o.equalsIgnoreCase(appUserDTO.getKaptcha())) {
            return Result.error("验证码错误");
        }

        //校验手机号码
        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("手机号不正确");
        }


        try {
            String login = appUserService.login(appUserDTO);
//            userService.selectUserByUsername(userDTO.getUsername());
            response.setHeader("token", login);
            //eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2NjQ3ODgyMzQsInVzZXJuYW1lIjoid2JoIn0.79DtkDZ9COZLbnTsbpLPpAZLoU3TXSXH6t-kRPboci8

            return Result.ok("登录成功", SecurityUtils.getSubject().getPrincipal());
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }

    /**
     * 修改密码
     *
     * @param appUserDTO
     * @return
     */
    @PostMapping("updateAppUserPassword")
    public Result updateAppUserPassword(@RequestHeader(name = "forgetPhoneCode") String token, @RequestBody AppUserDTO appUserDTO, HttpServletResponse response) {

        //手机号码验证
        boolean validPhoneNumber = RegularUtil.isValidPhoneNumber(appUserDTO.getAuPhone());
        System.out.println("validPhoneNumber:" + validPhoneNumber);
        if (!validPhoneNumber) {
            return Result.error("手机号不正确");
        }

        //校验验证码
        String PhoneCode = appUserDTO.getPhoneCode();

        String s = (String) redisTemplate.opsForValue().get(token);
        if (!StringUtil.isNotNull(s)) {
            return Result.error("验证码过期");

        }

        if (!s.equalsIgnoreCase(PhoneCode)) {
            return Result.error("验证码错误");
        }

        try {
            boolean success = appUserService.updateAppUserPassword(appUserDTO);
            return success ? Result.ok("修改成功") : Result.error("修改失败");
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }


    }

}
